<!-- 树形控件 -->
<template>
  <div class="c-tree">
    <a-input-search
      v-model:value="searchValue"
      placeholder="请输入关键字搜索"
      allowClear
      @change="onChangeHandle"
      @search="onSearchHandle"
    />
    <a-tree
      auto-expand-parent
      block-node
      default-expand-all
      class="mt10"
      :tree-data="currTreeData"
      :fieldNames="config.replaceField"
      @select="onSelectHandle"
    />
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { isNotEmpty } from '@/utils/index.js'
import axios from '@/api/index.js'

const props = defineProps({
  /**
   * 树形配置
   * {
   *   url: '/system/org/tree', // 获取树形数据的接口地址
   *   method: 'get', // 接口请求方式
   *   params: { type: 1 }, // 请求参数
   *   replaceField: { key: 'id', title: 'label', children: 'children' } // 字段名映射
   * }
   */
  config: {
    type: Object,
    required: true
  }
})

const searchValue = ref()
const treeData = ref([
  {
    title: 'parent 1',
    key: '0-0',
    children: [
      {
        title: 'parent 1-0',
        key: '0-0-0',
        children: [
          {
            title: 'leaf',
            key: '0-0-0-0'
          },
          {
            title: 'leaf',
            key: '0-0-0-1',
          },
        ],
      },
      {
        title: 'parent 1-1',
        key: '0-0-1',
        children: [
          {
            key: '0-0-1-0',
            title: 'sss',
          },
        ],
      },
    ],
  }
])
const currTreeData = ref(treeData.value)
const childrenField = props.config.children ?? 'children'
const titleField = props.config.title ?? 'title'

onMounted(() => {
  if (props.config.url) {
    getTreeData()
  } else {
    console.error('请配置树形组件的接口地址')
  }
})
async function getTreeData () {
  const result = await axios[props.config.method ?? 'get'](props.config.url, props.config.params)
  treeData.value = result ?? []
  currTreeData.value = result ?? []
}
function onChangeHandle (e) {
  if (!e.target.value) {
    onSearchHandle()
  }
}
function onSearchHandle (_searchValue) {
  if (_searchValue) {
    currTreeData.value = filterTreeData(treeData.value, _searchValue)
  } else {
    currTreeData.value = treeData.value
  }
}
// 递归过滤树形数据函数（不改变原始数据）
function filterTreeData (datas, _searchValue) {
  return datas.reduce((result, node) => {
    const newNode = { ...node } // 创建一个新的节点，避免直接修改原始数据
    // 如果当前节点匹配搜索关键字，则加入到结果中
    if (newNode[titleField].includes(_searchValue)) {
      result.push(newNode)
    }
    // 如果有子节点，则递归过滤子节点并加入到当前节点的子节点中
    if (newNode[childrenField]) {
      const filteredChildren = filterTreeData(newNode[childrenField], _searchValue)
      if (isNotEmpty(filteredChildren)) {
        newNode[childrenField] = filteredChildren
        result.push(newNode)
      }
    }
    return result
  }, [])
}
function onSelectHandle (selectedKeys) {
  emits('selected', selectedKeys[0])
}

const emits = defineEmits(['selected'])
</script>

<style lang="scss" scoped>
</style>
